BackForward

/*-------------------<-- Start of Description-->---------------------\
| Create special borders for word tables;                            |
|---------------------<-- End of Description-->----------------------|
|--------------------------------------------------------------------|
|------------<-- Start of Files or Arguments Needed-->---------------|
| Arguement:                                                         |
|    lines=r1:r2 c1:c2;                                              |
|         the line between 1st row and 2nd row are special bordered; |
|         the line between 1st column and 2nd column are special     |
|         bordered;                                                  |
|    properties=bold / double / None / Transparent -                 |
|         thick bordered / double bordered / or transparent (same as |
|         None);                                                     |
|         the order of the properties must be listed in the          |
|         corresponding order with the order of the lines;           |
|    wordref=wordsys; word reference; not necessary; default is      |
|         "wordsys";                                                 |
|-------------<-- End of Files or Arguments Needed-->----------------|
|--------------------------------------------------------------------|
|------------------<-- Start of Files Created-->---------------------|
| Example: %border(lines=c1:c2 r1:r2,properties=bold bold);          |
|          %border(lines=r-1:r-2 c1:c2,properties=bold none);        |
| Note: properties must be given in the order of the lines to be     |
|       bordered accordingly; otherwise, it will use the 1st         |
|       property to draw all the lines requested;                    |
| Usage: %border(lines=,properties=, wordref=wordsys);               |
\-------------------<-- End of Files Created-->---------------------*/
%macro border(lines=,properties=, wordref=wordsys)/parmbuff;
/*--------------------------------------------\
| Copy Right: Duo Zhou;                       |
| Created:  2-27-2001 11:33pm;                |
| Modified: 10-11-2002 9:39pm;                |
| Purpose:  Change the border format of tables|
|           in a word document;               |
\--------------------------------------------*/
%local rnum cnum _ri_ _ci_ icount nlines wordtemp linefmt startrnum endrnum
       startcnum endcnum iword bcount _i_ _j_ rowcount rownum properties inlines;
%let _wcount_=0;
%do %while(%length(%nrbquote(%scan(&syspbuff, %eval(&_wcount_+1), %str(,())))));
   %let _wcount_=%eval(&_wcount_+1);
   %let word=%qscan(&syspbuff, &_wcount_, %str(,()));
   %if (%index(%quote(&word),%quote(=))) %then %do;
      %let wordtmp=%sysfunc(dequote(%qscan(%quote(&word), 2, %str(=))));
      %if (%sysfunc(rxmatch(%sysfunc(rxparse($d)),&word))) %then %do;
         %let lines=&wordtmp;
      %end;
      %else %if (%index(%quote(%upcase(&word)),WORD)) or (%index(%quote(%upcase(&word)),WIN)) %then %do;
         %let wordref=&wordtmp;
      %end;
      %else %if (%index(%quote(%upcase(&word)),PROP)) %then %do;
         %let properties=&wordtmp;
      %end;
   %end;
   %else %do;
      %if (%sysfunc(rxmatch(%sysfunc(rxparse($d)),&word))) %then %do;
         %let lines=&word;
      %end;
      %else %if (%index(%quote(%upcase(&word)),WORD)) %then %do;
         %let wordref=&word;
      %end;
      %else %if (%index(%quote(%upcase(&word)),BOLD)) or (%index(%quote(%upcase(&word)),NONE)) or 
                (%index(%quote(%upcase(&word)),DOUBLE)) or (%index(%quote(%upcase(&word)),%quote(TRANSPARENT))) %then %do;
         %let properties=&word;
      %end;
      %else %Let wordref=&word;
   %end;
%end;

%let icount=1;
%let word&icount=%qscan(&lines, &icount, %str( ));

%do %while(%length(&&word&icount) gt 0);
   %let icount=%eval(&icount+1);
   %let word&icount=%qscan(&lines, &icount, %str( ));
%end;
%let nlines =%eval(&icount-1);
%let inlines=&lines;
%let lines=;


%let bcount=1;
%if (&properties eq) %then %do;
   %let properties=double;
%end;
%do fcount=1 %to &nlines;
   %let property&fcount=%qscan(&properties, &fcount, %str( ));
   %if &&property&fcount eq %then %do; %let property&fcount= ; %end;
   %else %do; %let bcount=%eval(&bcount+1); %end;
%end;
%if (%index(%upcase(&inlines),R)) %then %do;
   %let rowcount=1;
   %do _i_=1 %to &nlines;
      data sortedrows&_i_;
        length myfmt $20. myrownum $10.;
        format myfmt $20. myrownum $10.;
        myrownum="&&word&_i_";
        rorc=substr("&&word&_i_",1,1);
        myfmt="&&property&_i_";
        %if (%index(%upcase(&&word&_i_),R)) %then %do;
           %let rowcount=%eval(&rowcount+1);
        %end;
      run;
   %end;
   data sortedrownums;
     set %do _ij_=1 %to &nlines;
            sortedrows&_ij_
         %end;;
     run;
   proc sort data=sortedrownums; by descending rorc myrownum; run;
   data _null_;
      set sortedrownums end=last;
      length mylines mylinefmts $200.;
      format mylines mylinefmts $200.;
      retain mylines mylinefmts;
      if _n_=1 then do;
        mylines="";
        mylinefmts="";
      end;
      mylines=trim(left(mylines))||" "||trim(left(myrownum));
      mylinefmts=trim(left(mylinefmts))||" "||trim(left(myfmt));
      if last then do;
         call symput("lines", trim(left(mylines)));
         call symput("properties", trim(left(mylinefmts)));
      end;
   run;
%end;
data _null_;
   file &wordref lrecl=2000;
   length str $2000.;
   put '[TableSelectTable]';
   str= '[FormatBordersAndShading .ApplyTo = 2, .Shadow = 0, .TopBorder = 7, .LeftBorder = 7,
         .BottomBorder = 7, .RightBorder = 7, .HorizBorder = 1, .VertBorder = 1, .TopColor = 1,
         .LeftColor = 1, .BottomColor = 1]';
   put str;
   str='[FormatBordersAndShading .RightColor = 1, .HorizColor = 1, .VertColor = 1,
        .FromText = "0 pt", .Shading = 0, .Foreground = 0, .Background = 0, .Tab = "0",
        .FineShading = -1]';
   put str;
   /* Create double borders with internal single borders */
   %do iword=1 %to &nlines;
      put '[TableSelectTable]';
      put '[NextCell]';
      %let line&iword=%qscan(&lines,&iword,%str( ()));
      %if %qscan(&properties,&iword,%str( ())) ne %then %do;
         %let linefmt =%qscan(&properties,&iword,%str( ));
      %end;
      %if (%index(%upcase(&&line&iword),R))  %then %do;
         %let startrnum&iword=%qscan(&&line&iword,1,%str(()r:R,ROW row ));
         %let endrnum&iword=%qscan(&&line&iword,2,%str(()r:R,row ROW ));
         %if (&&startrnum&iword lt 0) %then %do;
            put '[StartOfRow]'; put '[StartOfRow]'; put '[EndOfColumn]'; put '[EndOfColumn]';
         %end;
         %do _ri_=1 %to %eval(%sysfunc(abs(&&startrnum&iword))-1);
            %if (&&startrnum&iword lt 0) %then %do;
            put '[EditGoTo .Destination = "l-1"]';
            %end;
            %else %do;
            put '[EditGoTo .Destination = "l+1"]';
            %end;
         %end;
         put '[TableSelectRow]';
         %do _ri_=%sysfunc(abs(&&startrnum&iword)) %to %eval(%sysfunc(abs(&&endrnum&iword))-1);
            %if (&&startrnum&iword lt 0) %then %do;
            put '[LineUp 1, 1]';
            %end;
            %else %do;
            put '[LineDown 1, 1]';
            %end;
         %end;
         %if (%index(%upcase(&linefmt),%quote(BOLD))) %then %do;
               str='[FormatBordersAndShading .HorizBorder = 3]';
            put str;
         %end;
         %else %if (%index(%upcase(&linefmt),%quote(DOUBLE))) %then %do;
               str='[FormatBordersAndShading .HorizBorder = 7]';
            put str;
         %end;
         %else %if (%index(%upcase(&linefmt),%quote(NONE)))  or (%index(%quote(%upcase(&word)),%quote(TRANSPARENT))) %then %do;
               str='[FormatBordersAndShading .HorizBorder = 0]';
            put str;
         %end;
         put '[TableSelectTable]';
         put '[NextCell]';
      %end;
      %else %if (%index(%upcase(&&line&iword),C)) %then %do;
         %let startcnum=%qscan(&&line&iword,1,%str(c()C:, col COL));
         %let endcnum=%qscan(&&line&iword,2,%str(c()C:, col COL));
         %if (not %index(%upcase(&lines),R)) %then %do;
            %do _ci_=1 %to %eval(&startcnum-1);
               put '[NextCell]';
            %end;
            put '[TableSelectColumn]';
            %do _ri_=&startcnum %to %eval(&endcnum-1);
               put '[CharRight 1, 1]';
            %end;
            %if (%index(%upcase(&linefmt),BOLD)) %then %do;
                  str='[FormatBordersAndShading .VertBorder = 3]';
               put str;
            %end;
            %else %if (%index(%upcase(&linefmt),DOUBLE)) and (not %index(%upcase(&lines),R)) %then %do;
                  str='[FormatBordersAndShading .VertBorder = 7]';
               put str;
            %end;
            %else %if (%index(%upcase(&linefmt),%quote(NONE)))  or (%index(%quote(%upcase(&word)),%quote(TRANSPARENT))) %then %do;
                  str='[FormatBordersAndShading .VertBorder = 0]';
               put str;
            %end;
         %end;
         %else %if (%index(%upcase(&lines),R)) %then %do;
            %if (&startrnum1 lt 0) %then %do;
            put '[StartOfRow]'; put '[StartOfRow]'; put '[EndOfColumn]'; put '[EndOfColumn]';
            %end;
            %do _ci_=1 %to %eval(&startcnum-1);
               put '[NextCell]';
            %end;
            put '[TableSelectCell]';
            %do _ri_=&startcnum %to %eval(&endcnum-1);
               put '[CharRight 1, 1]';
            %end;
            %do _rj_=1 %to %eval(%sysfunc(abs(&startrnum1))-1);
               %if (&startrnum1 lt 0) %then %do;
               put '[LineUp 1, 1]';
               %end;
               %else %do;
               put '[LineDown 1, 1]';
               %end;
            %end;
            %if (%index(%upcase(&linefmt),BOLD)) %then %do;
                  str='[FormatBordersAndShading .VertBorder = 3]';
               put str;
            %end;
            %else %if (%index(%upcase(&linefmt),DOUBLE)) %then %do;
                  str='[FormatBordersAndShading .VertBorder = 7]';
               put str;
            %end;
            %else %if (%index(%upcase(&linefmt),%quote(NONE))) or (%index(%quote(%upcase(&word)),%quote(TRANSPARENT))) %then %do;
                  str='[FormatBordersAndShading .VertBorder = 0]';
               put str;
            %end;
            put '[TableSelectTable]';
            put '[NextCell]';
            %do rownum=1 %to %eval(&rowcount-2);
               %if (&&endrnum&rownum lt 0) %then %do;
                  put '[StartOfRow]'; put '[StartOfRow]'; put '[EndOfColumn]'; put '[EndOfColumn]';
               %end;
               %do _rj_=1 %to %eval(%sysfunc(abs(&&endrnum&rownum))-1);
                  %if (&&endrnum&rownum lt 0) %then %do;
                  put '[EditGoTo .Destination = "l-1"]';
                  %end;
                  %else %do;
                  put '[EditGoTo .Destination = "l+1"]';
                  %end;
               %end;
               %do _ci_=1 %to %eval(&startcnum-1);
                  put '[NextCell]';
               %end;
               put '[TableSelectCell]';
               %do _ri_=&startcnum %to %eval(&endcnum-1);
                  put '[CharRight 1, 1]';
               %end;
               %let nextrow=%eval(&rownum+1);
               %if (%sysevalf(&&endrnum&rownum*&&startrnum&nextrow) >= 0) %then %do;
                  %do _rk_=%sysfunc(abs(&&endrnum&rownum)) %to %eval(%sysfunc(abs(&&startrnum&nextrow))-1);
                     %if (&&endrnum&rownum lt 0) %then %do; put '[LineUp 1, 1]'; %end;
                     %else %do; put '[LineDown 1, 1]'; %end;
                  %end;
               %end;
               %else %do;
                  %if (&&endrnum&rownum < 0) %then %do; put '[StartOfColumn 1]'; %end;
                  %else %do; put '[EndOfColumn 1]'; %end;
                  %do _rk_=1 %to %eval(%sysfunc(abs(&&endrnum&nextrow))-1);
                     %if (&&endrnum&nextrow > 0) %then %do; put '[LineDown 1, 1]'; %end;
                     %else %do; put '[LineUp 1, 1]'; %end;

                  %end;
               %end;
               %if (%index(%upcase(&linefmt),BOLD)) %then %do;
                     str='[FormatBordersAndShading .VertBorder = 3]';
                  put str;
               %end;
               %else %if (%index(%upcase(&linefmt),DOUBLE)) %then %do;
                     str='[FormatBordersAndShading .VertBorder = 7]';
                  put str;
               %end;
               %else %if (%index(%upcase(&linefmt),%quote(NONE))) or (%index(%quote(%upcase(&word)),%quote(TRANSPARENT))) %then %do;
                     str='[FormatBordersAndShading .VertBorder = 0]';
                  put str;
               %end;
               put '[TableSelectTable]';
               put '[NextCell]';
            %end;
            %let lastrow=%eval(&rowcount-1); %let last2row=%eval(&rowcount-2);
            %if (&last2row gt 0) %then %do;
               %if (&&endrnum&last2row <0) %then %let stop=&&startrnum&lastrow;
               %else %if (&&endrnum&last2row >0) %then %let stop=&&endrnum&lastrow;
            %end;
            %else %let stop=&&endrnum&lastrow;
            %if (&stop lt 0) %then %do;
               put '[StartOfRow]'; put '[StartOfRow]'; put '[EndOfColumn]'; put '[EndOfColumn]';
            %end;
            %do _ri_=1 %to %eval(%sysfunc(abs(&stop))-1);
               %if (&stop lt 0) %then %do;
               put '[EditGoTo .Destination = "l-1"]';
               %end;
               %else %do;
               put '[EditGoTo .Destination = "l+1"]';
               %end;
            %end;
            %do _ci_=1 %to %eval(&startcnum-1);
               put '[NextCell]';
            %end;
            put '[TableSelectCell]';
            %do _ri_=&startcnum %to %eval(&endcnum-1);
               put '[CharRight 1, 1]';
            %end;
            %if (&last2row gt 0) %then %do;
               %if (&&endrnum&last2row <0) %then %do; put '[StartOfColumn 1]'; %put 1: here; %end;
               %else %if (&&endrnum&last2row >0) %then %do; put '[EndOfColumn 1]'; %put 2: here; %end;
            %end;
            %else %if (&&endrnum&lastrow lt 0) %then %do; put '[StartOfColumn 1]'; %end;
            %else %do; put '[EndOfColumn 1]'; %end;
            %if (%index(%upcase(&linefmt),BOLD)) %then %do;
                  str='[FormatBordersAndShading .VertBorder = 3]';
               put str;
            %end;
            %else %if (%index(%upcase(&linefmt),DOUBLE)) %then %do;
                  str='[FormatBordersAndShading .VertBorder = 7]';
               put str;
            %end;
            %else %if (%index(%upcase(&linefmt),%quote(NONE))) or (%index(%quote(%upcase(&word)),%quote(TRANSPARENT))) %then %do;
                  str='[FormatBordersAndShading .VertBorder = 0]';
               put str;
            %end;
            put '[TableSelectTable]';
            put '[NextCell]';
         %end;
      %end;
   %end;
   put '[EndOfRow]';
   put '[EndOfRow]';
   put '[EndOfColumn]';
   put '[EndOfColumn]';
run;
%if (&nlines >=1) %then %do;
   /*** cleanup the temp datasets ***/
   proc datasets library=work nolist;
     delete
        %DO _i_ = 1 %TO &nlines;
          sortedrows&_i_
        %END; sortedrownums;
   run;quit;
%end;
%mend border;